12
תגובות

סטטיות ,סשן במסד, אינקלוד וHTTP

פתח mee ,
יש לי כמה שאלות :
1. קראתי בכל מיני פוסטים בSTACKOVERFLOW שיש כאלה שמתנגדים לשימוש בסטטיות. למה בעצם ?
ועוד תת שאלה בנושא: קראתי קצת על פריימוורקים ומדריכים בנושא וראיתי שיש כאלה שמתמשים בסטטיות, לדוגמה
App::request
Request::app
Vaild::names

(השמות הן רק דוגמה)
זה בסדר? כאילו לפעמים כן צריך סטטיות אני חושב, בVAILDATION שלא בכל מקום אתה תיצור מופע של זה אלא פשוט תשתמש במתודות וסלמאת, אבל מה הקטע להשתמש בזה בAPP או בדברים כאלה שהם מרכזיים לכאורה?

2. סשן במסד. למה צריך את זה? מה זה נותן לי? הרי סשן גם ככה נשמר בשרת אז למה הוא צריך להיות במסד? ואם הוא במסד איך הוא נמחק? ע"י curl? זה לא יותר מדי מנצל משאבים ?

3.אינקלוד: למה להשתמש באינקלוד (include)אם אפשר בריקוור(require) ? ולמה להשתמש בהם בלי להוסיף את הonce? מתי בעצם אני ארצה כפילות בדפים ומתי דף אחד לא יהיה חשוב לי אז אני פשוט אוותר עליו בלי שתוצג שגיאה?

4.קריאות/מתודות HTTP : האם ניתן להעביר מידע דרכם בין דף PHP לדף אחר?
כאילו , מHTML אתה פשוט מעביר בFORM פוסט או גט, ונגמר העניין
אבל בין דפי הPHP, ניתן להעביר אותם? נגיד דף registerVaild שמטפל בשגיאות יכול פשוט לשלוח את הנתונים לדף אחר(דף, לא מחלקה אחרת שמצויה בדף אחר אלא ממש דף ) , או שצריך דף register שיעשה אינקלוד לדף registerVaild?
ומה בנוגע לשאר הפונקציות בHTTP(פוט, דיליט, הד וכו') ניתן להשתמש בהם? צריך להשתמש בהם? ויש התייחסות לנושא מבחינת PHP ?

מצטער שאני חופר חח הנושאים פשוט מסקרנים אותי וכל יום עולים לי מחשבות חדשות

12 תשובות

avatar ענה Splash ב 19 לאוקטובר 2014 #

1.לא הבנתי מה הבעיה בעצם שאתה מעלה כאן אבל בעקרון הם עושים את זה כדי שתמנע בתכנות פרוצדוראלי בתוך קוד מונחה עצמים בכללי הרבה יותר קל גם מבחינה תכנותית למצוא את המידע שחיפשת אם למשל שכחתי מה ה key במערך server שבו מאוחסן האייפי של המשתמש,ברגע שזה מופרד למתודה בצורה הזאת-

Request::getclientip

הרבה יותר קל לי למצוא את המתודה משום שהעורך יודע להפנות אותי למתודות של אותה מחלקה ואז לפי השם אני יודע מה הפעולה עושה.
לעומת זאת כאשר אתה כותב בצורה פרוצדולארית אין לך את ההשלמה האוטומטית הזאת ותמיד יכולה להתפקשש לך איזה עוד בטעות ככה שבמקום שתכתוב remote יצא לך פתאום emote או משהו בסגנון ואין שום עורך שיתריע לך על שגיאה כזאת.


2.מאחר והמסד נתונים מיועד לשמירה,כתיבה ומחיקה של נתונים הוא יכול להיות מועיל יותר במקרים של הרבה סשנים.בכללי אם השרת שלך מאפשר לך לאחסן את הנתונים על הזיכרון הוירטואלי בפועל זה יהיה הדריבר הכי טוב משום שבכלל לא מעורבת כאן כתיבה\מחיקה מדיסק [memcache,redis]

לגבי המחיקה,הוא נמחק בדיוק כמו שהסשן בקובץ נמחק,כל פעם שמגיעה בקשה יש קוד שמרגיל מספר מתוך X במידה והמספר הוגרל הפעולה של המחיקה נכנסת לפעולה.
אם זה בקבצים אז הוא סורק את התיקיה ומוחק סשנים שפג תוקפם.
במקרה של ה DB זה מבוצע ע"י שאילתה שבודקת את הזמן קריאה האחרון ואם פג תוקפו היא מוחקת אותו משם.

3.require במידה והוא לא קיים הוא מבצע die\exit לתכנית ובעצם העמוד יטען רק עד אותו חלק.
ב include לעומת זאת העמוד ימשיך להיטען.
אתה למעשה אף פעם לא תרצה למעשה להשתמש ב once ,מדובר בפונקציה איטית בהרבה מהפונקציית אב משום שלפני שהיא מבצעת include/require היא צריכה לגשת לזכרון לבדוק אם הקובץ נפתח בעבר.
במידה אתה משתמש ב OOP אתה יכול לעבוד עם ה autoload ובעצם לדמות את הפונקציה בעזרת class_exist.
אם לא אז תצטרך לזכור פשוט כל קובץ רק פעם אחת
אלה אם כן באמת אין לך כוח ואז אתה יכול לדחוף once לכל ה include/require שלך אך אני חושב שזה מלמד הרגל רע שקשה להיפטר ממנו אחר כך.

4.ניתן להעביר מידע בין דפים בעזרת coockie\session
את החלק השני כבר לא הבנתי ותצרך להסביר טוב יותר את עצמך

avatar ענה mee ב 19 לאוקטובר 2014 #

1. התכוונתי ביחס למתודות רגילות, למה להשתמש במתודה סטטית ולא להשתמש במתודה רגילה כpublic ?
2. אבל במקרה של קבצים המנוע של הסשן עצמו מוחק אותם ואם זה בDB אני צריך להגדיר את זה בCURL או כל דבר אחר לא? הרי זה טבלה שאני יוצר היא לא מובנית בPHP ..
3.אז שחכנו מהONCE, מה בנוגע לאינקלוד והריקוור? מתי אני יעדיף אינקלוד ?
4. פשוט להעביר את כל נתוני ההרשמה לדוגמה בקוקיז ? זה לא מסוכן קצת ?
נגיד בקשות PUT , שזה סוג של בקשה כמו POST וGET (אם הבנתי נכון) , איך אני שולח ומקבל אותן דרך PHP ? והאם זה הכרחי לי באיזושהי צורה ?

avatar ענה Splash ב 19 לאוקטובר 2014 #

1. משום שאתה לא רוצה ליצור אוביקט חדש כל פעם שאתה רוצה לדעת באיזה route אתה נמצא,או כל פעם שאתה רוצה לקבל את האייפי של המשתמש זה סתם בזבוז זכרון וגם די מעצבן לכתוב את זה.

2.עשית קצת סלט,המנוע של php בכלל לא מאפשר סשנים דרך מסדי נתונים,הוא יודע לעבוד אך ורק עם קבצים.
מה שאתה ראית זה פרימוורק\ספריה שמחקה את הפעילות של המנוע סשנים של php אבל לא משתמשת בו ובכך מאפשרת לך לבחור בין מספר דריברים.
ל curl אין שום קשר לכאן,curl הוא פרוטוקול להעברת מידע וכמו שרשמתי,כמו שרשמתי המחיקה בד"כ מבוצעת ע"י הגרלת מספר בטעינת העמוד אבל כל מפתח כותב בדרך שלו
אז כדי לענות לך על השאלה איך המנגנון מחיקה עובד צריך לדעת באיזה ספריה אתה משתמש ושם לבדוק.

3.כאשר הקובץ הוא קריטי לטעינה תשתמש ב require אחרת אתה יכול להשתמש ב include
אם יש לך התלבטות בין השניים תשתמש ב require.
בכל מקרה שלא יהיה זו שגיאה שלא אמורה לקרות אלה אם כן מישהו מחק את הקבצים האלה \ לא כללת את הקובץ נכון.

4.אתה ממש לא אמור לעשות את זה בצורה הזאת.
יש לך בעקרון יש לך שתי אפשרויות-
1.ליצור עמוד של ולידציה ועמוד של טופס ,כאשר הטופס נשלח לולידציה,אם הכל הלך כמו שצריך -> תרשום את המשתמש אחרת -> חזור אחורה ותקן שגיאות [כאן נכנס הסשן לפעולה,אתה מכניס את כל השגיאות שהיו לסשן יחד עם השדות ובעמוד של הטופס טוען את הנתונים הללו]
2.אפשרות אחרת זה לשים את שניהם באותו עמוד כאשר הדבר היחיד שמבדיל ביניהם זה בדיקה האם קיים ה post,אם לא -> תראה את הטופס
אם כן -> תבצע ולדיציה -> הכל הלך קשורה ? -> תרשום את המשתמש אחרת -> תציג את הטופס עם שגיאות.
מבחינת php אי אפשר באמת לשלוח בקשות post/put/delete וכו' דרך המשתמש,ניתן רק לבצע redirect [get[
אפשר סוג של "לרמות" את עצמך ע"י שליחה של curl אבל ממש לא ככה עושים ולידציה של טפסים.

avatar ענה intval ב 19 לאוקטובר 2014 #

1. אני גם מאלה שמתנגדים לסטטיות, כי זה יוצר הרבה בעיות בעתיד. זיכרון שמשותף להרבה חלקים בתוכנה זה בדרך כלל מקום לבעיות וטעויות. אמנם ב-PHP פחות והם גם פחות קריטיים. בנוסף קשה לבצע בדיקות יחידה על קוד כזה (סיפור ארוך).

הסיבה שפריימוורקים משתמשים בזה (app::...) היא בשביל נוחות בלבד. כדי שאנשים לא יצטרכו לשמור במשתנה את המופע והלעביר מפה לשם בכל התוכנה, לכן זהו טריק לנוחות בלבד.

2. סשן במסד נועד למקרים שבהם אתה משתמש בכמה שרתים במקביל בגלל עומס. בגלל שסשן נשמר על שרת אחד ספציפי, אם הבקשה הבאה של המשתמש תגיע לשרת אחר - הוא יאבד את ההזדהות.


3. תלוי במקרה שלך. אולי יש לך קוד של מונה כניסות. הוא לא קריטי מדי בשביל העמוד שלך ואין לך צורך לעצור את הפעילות של האתר במקרה הזה, לאומת זאת טעינה של מחלקת מסד נתונים יכולה להיות קריטית. ה-once זה עוד כלי נוחות למי שעובד בצורת "קוד בלאגן" ואין לא ומשג האם משהו נטען או לא.


4. טכנית אפשר, אבל require יהיה מהיר יותר וגם מישהו אחר לא ישלח לך נתונים לא תקינים ישר לשלב 2

avatar ענה mee ב 20 לאוקטובר 2014 #

1. הבנתי :) תודה רבה לכם !!

2. התבלבלתי חח התכוונתי cron jobs ולא curl אני פשוט רגיל לזכור דברים עם האות הראשונה שלהם וזה מבלבל אותי שזה באותה האות חח
אז בעצם כל ספריה עובדת במצב שונה, ואם אני רוצה ליצור ספריה משלי ? זאת אומרת , קלאס משלי שיעבוד עם סשן מבוסס שרת - באיזה דרך כדאי להשתמש ?
ומה בנוגע לאתרים נגיד כמו פייסבוק או כל אתר שמתחיל בקטן בשרת אחד , איך הוא יעבור לשינוי כלכך גדול של להחליף את כל הסשנים שיהיו מבוססים על מסד ?

3.אז בקיצור, require כמעט תמיד . Icnlude רק בדברים זניחים יותר. ועל הONCE אפשר לוותר כי עדיף AUTOLOAD או מחלקה לטעינת עמודים , גם אני חושב שעדיף יותר ככה :)

4.הולידציה הייתה סוג של דוגמה תאמת חח לא עלה לי משהו אחר של שימוש בזה וכנראה שגם אין שימוש בזה.
אז איך שולחים בקשות PUT ובקשות אחרות? כאילו, למה יש את זה אם לא נתקלתי בזה ואין לי אפשרות לממש/לעשות עם זה משהו ?

avatar ענה intval ב 20 לאוקטובר 2014 #

2. זה לא שינוי כזה גדול כמו שאתה חושב, באיחוד אם תכננת את המערכת שלך נכון. סשן גם לא חייב להימחק על ידי קרון. המסד יכול למחוק אותו בעצמו או להתעלם ממנו אם פג תוקפו. וכן, אתרים מתחילים בקטן ואחר כך משנים את מקום שמירת הסשן.

4. אם לא נתקלת בזה, לא אומר שזה לא קיים. מצד שני מתוך 11 מתודות ה-HTTP הקיימות, היום משתמשים הרבה בארבעה: get, post, put, delete
בשאר המתודות משתמשים פחות. איך לעשות את זה? כשאתה שולח בקשת ajax מהדפדפן, או בקשת curl מתוך הסקריפט - אתה יכול לרשום בצורה מפורשת באיזו מתודה להשתמש. במה בדיוק תשתמש - זו בחירה שלך משיקולי נוחות.

avatar ענה mee ב 21 לאוקטובר 2014 #

2. אולי כדאי ליצור מעטפת כזאתי של קלאס שממנו עובדים אם הסשנים והוא בעצם יורש מקלאס אחר, ואז במקרה של מעבר פשוט משנים את האב כי גם ככה משתמשים רק בבן, אולי אפילו מחלקה אבסטרקטית כדי למנוע בכלל שימוש .

4.אבל לרוב משתמשים בPOST וGET?

ועוד שאלה שהיא בעצם קשורה ל1 : איך אני יודע איזו מחלקה עדיף לי לעשות סטטית -מטעמי נוחות כמובן- ואיזו מחלקה אני כן רוצה שיצרו מופע משלה?
כי נגיד יש לי קלאס של ולידציה - אז הוא יהיה סטטי כי לא בכל פרוצדורה של ולידציה אני יתחיל ליצור מופעים
אבל מצד שני קלאס לשליחת אימייל - לא מצאתי ברשת קלאס כזה שהשליחה בו היא סטטית אבל לדעתי יש מקום לעשות דבר כזה סטטי - כי נגיד באספשיינס או בכל מיני דברים שנוגעים למשתמש או שלא נוגעים אליו אני ארצה לשלוח אימייל אני אצטרך ליצור מופע חדש לא עדיף לעשות את זה סטטי ?
בקיצור השאלה שלי היא: מתי להשתמש במחלקות סטטיות , תוך כדי צימצום השימוש בסטטיות ?
כדי לא להשתמש בזה יותר מדי אבל כן להשתמש כשצריך ?

avatar ענה Splash ב 21 לאוקטובר 2014 #

2.בהחלט,שימוש במחלקה אבסטרקטית\interface יקל על המעבר בין דריברים.

4.כן,לרוב משתמשים ב get ו post אבל מבחינת התקן זה לא נכון,בדיוק כמו שמתי שיוצרים תגובה חדשה [או בכללי משהו חדש] אמור לחזור ההדר 201 - created
ובכל זאת בהרבה מקרים חוזר ההדר 200,ובעוד מקרים של הדרים אחרים.
בכל מקרה זה לא משפיע על התפקוד של הדפדפן ולכן הייתי אומר שזה החלטה שלך.
--------------------------------------------------------------------------------------------------
בתכנות לא הכל זה שחור ולבן,יש אנשים שמעדיפים לעשות X ויש אנשים שמעדיפים Y,אין כאן נכון או לא נכון,אם אתה חושב שמתודה סטטית תיהיה נוחה יותר עבורך אז תבצע זאת באמצעות מתודה סטטית.

לגבי מתי זה יותר מידי,הרבה אנשים משתמשים בפעולות\משתנים סטטיים בתור פעולות גלובליות ובעצם ממשים את אותו קוד פרוצדוראלי פשוט בשיטה שאולי מזכירה תכנות מונחה עצמים אבל אין לה שום קשר לכך.
ברגע שכל הקוד שלך הוא סטטי,הוא לא מונחה עצמים אלה מונחה משתנים\פונקציות.

ברגע שאתה עובד רק בצורה סטטית מאוד קשה להגיד לעצמך למי אתה פונה.
אז בסדר יש לנו מחלקה בשם Person ויש לנו מתודה סטטית בשם WentToWork.
אבל מי זה אותו person ? מה השם שלו ? בן כמה הוא ? איפה הוא עובד בכלל ?
את כל הנתונים האלה אתה תצטרך להכניס ידנית.
לעומת זאת ברגע שאתה יוצר אוביקט אתה יכול להגיד ,לבן אדם קוראים דני הוא בן 18 ועובד בדומינוס.
ואז במידה והמחלקה WentToWork תרצה בעתיד לקבל את העבודה שאליה אותו אדם הלך היא תוכל לקבל זאת בלי לבצע שום שינויים בקוד למעט המתודה עצמה.
בעוד שבמידה ותעבוד בצורה סטטית אתה תצטרך עכשיו להוסיף בכל מקום שבו אתה קורא לפונקציה WentToWork פרמטר שבו מאוחסן המקום עבודה,לא כל כך נעים.

לסיכום,על אף שהתכנות מונחה עצמים לפעמים נראה לא יעיל,ולא תמיד אתה משתמש בכל הפמטרים של אותה מחלקה,המבנה הזה מאוד מקל עליך במקרה של שינויים בקוד ואין מה לעשות,לפעמים מוותרים טיפה על הביצועים לטובת התחזוקה של הקוד.

avatar ענה mee ב 22 לאוקטובר 2014 #

אבל זה שונה כי מחלקות כמו Person מייצגות דמות מייצגות משהו שהוא סוג של מוחשי, סוג של משהו שאתה יכול להגדיר(כמו דני שעובד בדומינוס)
אבל מחלקה כמו Vaild מה הן מייצגות? פילטרים/בדיקות זה לא עצם כלשהו ,זה בעצם אוסף של מתודות שבמקום לכתוב אותן כפונקציות רגילות בחרת לכתוב אותן בתוך מחלקה, ותקן אותי אם אני טועה בחשיבה או באיזשהו משו :)

במחלקות כמו פרסון אתה גם מכניס ערכים שהם קבועים פחות או יותר - שם גיל עבודה
ואפילו מכניס למסד או מוציא מהמסד ומעביר את זה לתוך פרסון ואפשר לשחק עם זה
אבל בווילד בכל שימוש במתודה אתה בעצם בודק דברים שונים וכנראה שגם לא קשורים לגמרי אחד לשני , פעם תבדוק אימייל וסיסמה בפעם הבאה תבדוק קישור וכן הלאה וכן הלאה
אלו סוגים שאני יודע להבדיל(לפחות בשבילי) בין מחלקה שהיא כולה סטטית לבין מחלקה שמייצגת לי עצם.
השאלה שלי היא במחלקות שאני מתלבט, שהן בצד האפור שהן אולי כן מייצגות איזשהו עצם אבל מצד שני אני צריך אותן לגישה חופשית ומעוד צד, אני לא רוצה שתהיה תלות במחלקה (ככה שאני לא יצהיר עליה) אבל זה גם קצת מיותר להכניס אותה בתוך הקונסטקטור..

חשבתי על ליצור מחלקה כוללת שתכיל מערך עם מופעים של מחלקות כאלה(כמו שאני עושה עם המחלקה של המסד נתונים שלי וככה אני מאפשר לעצמי להשתמש בכמה מסדים בו זמנית) וכל פעם שארצה אני פשוט יחזיר את המופע מתוך המערך הזה(בעזרת מתודה מתאימה). אבל הבעיה שחשבתי עליה היא שזה יקח לי המון משאבים , או שזה לא יקח ? לא יודע לא ניסיתי לחפש בגוגל אבל לא ידעתי איך פאקינג לנסח את זה חחח

מצטער אם סיבכתי את זה קצת חח מקווה שהבנת אותי
יש לך פתרון לזה ?

avatar ענה Splash ב 22 לאוקטובר 2014 #

ברור שלא תמיד תיהיה לך מחלקה של משהו שנוח להגדיר,זה פשוט הכי קל להסביר על מחלקות מהסוג הזה כדי לתפוס את הרעיון הכללי.

במחלקה Validation כן יש לך ייצוג של אובייקט,יש לך חוקים והמקומות שהם צריכים להתקיים בהם [חוקי תנועה - בכביש,חוק השבות - בישראל,החוקים של הפורום הזה - באתר הזה ספציפית] ככה שלמעשה החוקים הם מערך שה key שלו זה המקום והערך שבתוכו [או עוד מערך או מופרד ע"י פסיק\whatever you want] זה החוקים.
בנוסף למחלקה יש משתנה errors ששם נשמרים כל השגיאות במידה ויש.
מבחינת מתודות אז צריך בנאי שייצר לנו את המערך,אפשר להוסיף מתודה add שתוסיף עוד חוקים למערך,מתודה validate שתאמת את החוקים,מתודה IsValid שתבדוק אם החוקים עברו בהצלחה ו GetErrors שתחזיר את כל השגיאות שקיימות.

המחלקה validation אמורה להיות אוביקט משום שהיא עונה על הקריטריונים המובהקים שלו - יש לה משתנים ומתודות קבועות.
לעומת זאת ניתן למצוא פריימוורקים שעומדים איפה שהוא באמצע,בלראבל יש אוביקט למחלקה אבל היצירה יחד עם הולידציה מבוצעת בצורה סטטית ומחזירה אוביקט.
קוד דוגמא מהאתר שלהם -

$validator = Validator::make(
    array('name' => 'Dayle'),
    array('name' => 'required|min:5')
);

כרגע $validator מחזיק את האוביקט בתוכו [אחרי שכבר עבר ולידציה] ויש לנו גישה לכל המאפיינים של המחלקה - האם החוקים עברו בהצלחה,ואם לא איזה שגיאות קיבלנו ואיפה.

למעשה היה ניתן לקבל את אותה תוצאה בדיוק במידה והיית עובד עם הבנאי רק שמאחר ואנחנו לא רוצים לקרוא לפונקציות בבנאי עצמו אלה רק לאתחל את האוביקט אנחנו נפריד בין שני החלקים,יש חלק אחד שמקבל את הפרמטרים וחלק שני שעושה ולידציה.

בכל מקרה אם אתה חושב שמתודה סטטית היא נכונה יותר במקרה הזה אז תעשה אותה סטטית

avatar ענה mee ב 26 לאוקטובר 2014 #

אז כאילו הבנאי פה הוא פרייבט והmake מתאחל אותו כל פעם ? כמו סינגלטון רק שהוא לא מחזיר את האינטסט אלא מאתחל מחדש ?

avatar ענה Splash ב 26 לאוקטובר 2014 #

הבנאי הוא לא private אבל המתודה make יודעת לשלוח לו את הפמטרים שהוא צריך,בנוסף כמו שאמרתי היא לא רק יוצרת אוביקט חדש של validation אלה גם מבצעת את הולידציה תוך כדי ככה שאתה מקבל כמה פעולות במקביל.
במקרה שלך אולי הבנאי של validation כן יכול להיות private.
זה שיש מישהו באינטרנט שמממש את הקוד בצורה X לא אומר שזה בהכרח הדרך הנכונה לעבוד. באותה מידה יש פרימוורקים שדורשים ממך ליצור אוביקט עם החוקים ואז במתודה נפרדת מבצעים את הולידציה.